package org.xurui.sxl.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.springframework.util.StringUtils;
import org.xurui.sxl.protocol.cache.ConcurrentMapCache;
import org.xurui.sxl.protocol.command.CmdCodec;
import org.xurui.sxl.protocol.enums.CommandEnum;
import org.xurui.sxl.protocol.utils.BinaryUtils;
import org.xurui.sxl.protocol.utils.LonLat;
import org.xurui.sxl.protocol.utils.NumberUtils;
import org.xurui.sxl.protocol.utils.SxlMessageUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 岗位设置/学校设置 B、多边形范围
 */
@Slf4j
public class CmdCodec_POSTSELFM implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.POSTSELFM.name().equals(cmd);
    }

    @Override
    public boolean supportsRelayCmd() {
        return true;
    }

    @Override
    public List<DeviceMessage> parsePayload(String payload, FromDeviceMessageContext context) {
        //设备回复格式：*XX,YYYYYYYYYYYYYYY,V4,POSTSELFM,seq,para,HHMMSS,S,latitude,D,longitude,G,speed,pdop,DDMMYY,tracker_status#
        //设备回复示例：*TJ,2020916301,V4,POSTSELFM,130305,1,4,2234.3355,11351.7008,2234.2668,11351.6343,2234.2131,11351.7159,2234.2881,11351.7856,130306,V,2230.7021,N,11355.1445,E,0.0,2.8,271112,FFFFFFFF#
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        String[] payloadArr = payload.replaceAll("\\*","").split(",");
        String deviceId = payloadArr[1];
        report.setDeviceId(deviceId);
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(deviceId+"_"+CommandEnum.POSTSELFM.name()+"_"+payloadArr[4]);
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = deviceId+"_"+payloadArr[4];
        }

        report.setFunctionId(CommandEnum.POSTSELFM.name());
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        String[] paraArr= Arrays.copyOfRange(payloadArr,4,payloadArr.length-10);
        String para="";
        for (int i=1;i<paraArr.length;i++){
            // System.out.println(paraArr[i]);
            if(i==1){
                para=paraArr[i];
            }else{
                para=para+","+paraArr[i];
            }
        }
        int j=4+paraArr.length-1;

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[j+1]);
        properties.put("s",payloadArr[j+2]);
        properties.put("latitude",BinaryUtils.getWgs84LonLat(payloadArr[j+3],"lat"));
        properties.put("d",payloadArr[j+4]);
        properties.put("longitude",BinaryUtils.getWgs84LonLat(payloadArr[j+5],"lon"));
        properties.put("g",payloadArr[j+6]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[j+7]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[j+8]));
        properties.put("upday", payloadArr[j+9]);
        String trackerStatusHex = payloadArr[j+10];


        Map<String,Object> trackerStatusMap = parseTrackerStatus(trackerStatusHex);
        properties.put("trackerstatus",trackerStatusMap);
        report.setOutput(properties);

        //TODO 更新状态
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message,String zzs) {
        //平台下发消息
        //格式：*XX,YYYYYYYYYYYYYYY,POSTSELFM,HHMMSS,POSTID,NUM,POST_LAT1,POST_LON1,POST_LAT2,POST_LON2,POST_LAT3,POST_LON3,,,#
        //例子：*TJ,2020916301,POSTSELFM,130305,1,4,2234.3355,11351.7008,2234.2668,11351.6343,2234.2131,11351.7159,2234.2881,11351.7856#
        //参数说明：POSTID 岗位/学校组 ID，1-3，最多 3 组
        //参数说明：NUM 多边形点数，最少 3 个点，最多 20 个点
        //参数说明：POST_LAT 岗位/学校纬度；wgs84，格式：DDFF.FFFF，度度分分.分分分分
        //参数说明：POST_LON 岗位/学校经度，wgs84，格式：DDFF.FFFF，度度度分分.分分分分

        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            String postId="";
            if(paramsMap.get("postId")!=null && !paramsMap.get("postId").equals("")) {
                postId=paramsMap.get("postId").toString();
            }
            String num="";
            if(paramsMap.get("num")!=null && !paramsMap.get("num").equals("")) {
                num=paramsMap.get("num").toString();
            }

            String[] coordinate= new String[]{};
            if(paramsMap.get("coordinate")!=null && !paramsMap.get("coordinate").equals("")) {
                coordinate=paramsMap.get("coordinate").toString().split(",");
            }
            if(coordinate.length==0){
                log.error("岗位/学校纬度为空请重新填写");
                return null;
            }

            if(coordinate.length>0) {
                if(coordinate.length<6|| coordinate.length>40){
                    log.error("多边形点数，最少 3 个点，最多 20 个点，该参数岗位/学校纬度点数不正确请重新填写");
                    return null;
                }
                if(!StringUtils.isEmpty(num)){
                    if ( Integer.parseInt(num)*2!= coordinate.length) {
                        log.error("该参数岗位/学校纬度长度与岗位/学校经度不一样请重新填写岗位/学校经度");
                        return null;
                    }
                }


                for (int i=0;i<coordinate.length;i++){
                    LonLat lonLat=new LonLat();
                    lonLat.lng=Double.parseDouble(coordinate[i]);
                    lonLat.lat=Double.parseDouble(coordinate[i+1]);

                    LonLat aa=BinaryUtils.gcj02towgs84(lonLat);

                    String lat=BinaryUtils.getLonLatToWgs84(String.valueOf(aa.lat),"lat");
                    coordinate[i]=lat;
                    System.out.println(lat);
                    String lon=BinaryUtils.getLonLatToWgs84(String.valueOf(aa.lng),"lon");
                    coordinate[i+1]=lon;
                    System.out.println(lon);
                    i++;
                }


            }






            String time = SxlMessageUtils.getTimeHHMMSS();//DateFormatUtils.format(new Date(),"HHmmss");

            SxlMessageUtils.SxlCmd sxlCmd=SxlMessageUtils.SxlCmd.getInstance();
            sxlCmd.appendAndAddSeparator(zzs)
                .appendAndAddSeparator(message.getDeviceId())
                .appendAndAddSeparator(CommandEnum.POSTSELFM.name())
                .appendAndAddSeparator(time)
                .appendAndAddSeparator(postId)
                .append(num)
                .append(SxlMessageUtils.CMD_SEPARATION);
            for (int i=0;i<coordinate.length;i++){
                if(i<coordinate.length-1){
                    sxlCmd.appendAndAddSeparator(coordinate[i]);
                }else {
                    sxlCmd.append(coordinate[i]);
                }
            }
            ConcurrentMapCache.getInstance().set(message.getDeviceId()+"_"+CommandEnum.POSTSELFM.name()+"_"+time,message.getMessageId(),60*3*1000);

            return sxlCmd.buildEncodeMessage();
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.WIFISCAN.name(),message);
            }
            return null;
        }

    }
}
